/**
 * 
 */

package com.chengyu.eyc.aop;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.chengyu.eyc.annotation.OperateLog;
import com.chengyu.eyc.model.EycLog;
import com.chengyu.eyc.service.EycBaseService;
import com.github.binarywang.wxpay.exception.WxPayException;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author kevin
 *
 */
@Slf4j
@Component
@Aspect
@AllArgsConstructor
public class OperateLogAspect {

    private EycBaseService eycBaseService;

    @Around(value = "@annotation(operateLog)")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint, OperateLog operateLog) throws WxPayException {
        try {
            Signature signature = proceedingJoinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature)signature;
            String classCommentName = methodSignature.getMethod().getDeclaringClass().getAnnotation(Api.class).tags()[0];

            String[] sourceName = signature.getDeclaringTypeName().split("\\.");
            String className = String.join(".", sourceName) + (StrUtil.isNotBlank(classCommentName) ? "[" + classCommentName + "]" : "");

            String methodCommentName = methodSignature.getMethod().getAnnotation(ApiOperation.class).value();
            String methodName = signature.getName() + (StrUtil.isNotBlank(methodCommentName) ? "[" + methodCommentName + "]" : "");
            // 参数名数组
            String[] parameterNames = ((MethodSignature)signature).getParameterNames();
            // 构造参数组集合
            List<Object> argList = new ArrayList<>();
            for (Object arg : proceedingJoinPoint.getArgs()) {
                // request/response无法使用toJSON
                if (arg instanceof HttpServletRequest) {
                    argList.add("request");
                } else if (arg instanceof HttpServletResponse) {
                    argList.add("response");
                } else {
                    argList.add(JSONUtil.toJsonStr(arg));
                }
            }
            EycLog eycLog = new EycLog();
            eycLog.setPackageNme(className);
            eycLog.setMethodNme(methodName);
            eycLog.setLogContent(String.format("请求参数：%s -> %s", JSONUtil.toJsonStr(parameterNames), JSONUtil.toJsonStr(argList)));
            eycBaseService.insertEycLog(eycLog);
            return proceedingJoinPoint.proceed();
        }catch(WxPayException e) { 
            throw e;
        }catch (Throwable e) {
            log.error(e.getMessage(), e);
            return null;
        }

    }

}
